#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function
import simpla
import uuid
from os.path import join
import json
import random
import threading
import time
from threading import Thread
import rou.constants as rc
import sumolib.net
import traci
# import libsumo as traci
import traci.constants as tc
from kafka import KafkaProducer, KafkaConsumer
from traci import TraCIException
import platoonUtils
import sumo_utils
from constants import KAFKA_HOST, TRAFFIC_FLOW_TOPIC, TRAFFIC_FLOW_TOPIC_WEBGL, VIR_DEVICE_STATUS_TOPIC, \
    CA_VEHICLE_FORMATION_INFORMATION
from httpserver import HttpInterface
from plexe import Plexe
from rou._rou_configuration import RoutConfig
from scene.plexe_enum import Plexe_enum
from utils import kafka_util, sumo_main1init_util
from utils.gantry_util import get_gantry_info, get_speed_limit_points, get_gantry_info_HTF
from utils.emergencyLane_util import get_emergencyLaneConfig_info, get_emergencyLaneControl_info
from utils.rou_utils import parse_route, MTF_parse_route
from utils.station_util import get_station_number, get_edge

import queue
from utils.kafka_util import real_vehicle_queue

# 全局区域
GLOBAL_POLYGON = [(1272.69, 1313.02), (1941.95, 1266.86), (2581.83, 1004.62), (2625.89, 954.26), (2116.08, 433.97),
                  (1637.74, 280.81), (330.70, -4.51), (-15.47, 24.86), (-67.92, 297.60), (664.28, 582.92),
                  (1272.69, 1313.02)]
# 全局中心点
GLOBAL_POLYGON_CENTER = [(1305.496234759936, 678.856887685563), (1305.496234759937, 678.856887685563),
                         (1305.496234759937, 678.856887685564), (1305.496234759936, 678.856887685564)]
# 与编队车辆有关
count_step = 0
# 主路限速区监控
limit_polygon = {}
# 主路限速是否开启标识
SPEED_LIMIT_SIGN = False
# 主路限速区标志
SPEED_LIMIT_POLYGON_SIGN = 'LIMIT_POLYGON'
# kafka 门架或者匝道管控灯
vir_gantry_dict = dict()
emergency_dict = dict()
special_dict = dict()

vehicle_dict = {}
vir_ramp_light = 1
speed_limit_point_list = []
speed_limit_list = []
speed_gantry_asc = []
# locusQueue = queue.Queue(maxsize=2000)
# 存放kafka传来的真车数据


# 恶劣天气区域监控
bad_weather_polygon = {}
# 恶劣天气标志
BAD_WEATHER_POLYGON_SIGN = 'BAD_WEATHER_POLYGON_'

topology = None


def async_call(fn):
    def wrapper(*args, **kwargs):
        Thread(target=fn, args=args, kwargs=kwargs).start()

    return wrapper


arivedNumber = 0
leader_ids = [Plexe_enum.LEAD.value, Plexe_enum.FOLLOW_ONE.value, Plexe_enum.FOLLOW_TWO.value,
              Plexe_enum.FOLLOW_THREE.value]
# 车辆如果消失的话 会自动添加车辆 车辆路由字典
arrived_depart = dict
# 混合流仿真保存发车的车辆id和车辆路由
depart_info = {}


# @async_call
def main1(userId=None, task_id=None, rou_cfg=None, sumo_cfg_file=None, sumo_net_file=None, gui=True, resource=None):
    global count_step, limit_polygon, bad_weather_polygon, topology, SPEED_LIMIT_SIGN, vir_gantry_dict, \
        speed_limit_point_list, speed_limit_list, speed_gantry_asc, arrived_depart
    # ======================路网信息初始化============================
    frame_info = get_gantry_info()
    frame_emergencyLaneConfig = get_emergencyLaneConfig_info()
    frame_emergencyLaneControl = get_emergencyLaneControl_info()

    sumo_net_instance = sumolib.net.readNet(sumo_net_file, withInternal=True, withLatestPrograms=True)
    sumo_utils.start_sumo(sumo_cfg_file, False, gui=gui)
    traci.polygon.add('GLOBAL_POLYGON_CENTER', GLOBAL_POLYGON_CENTER, (1, 0, 1))
    traci.polygon.subscribeContext('GLOBAL_POLYGON_CENTER',
                                   tc.CMD_GET_VEHICLE_VARIABLE, 10000,
                                   [tc.VAR_SPEED, tc.VAR_DECEL, tc.VAR_DISTANCE, tc.VAR_TYPE, tc.VAR_POSITION,
                                    tc.VAR_ROAD_ID, tc.VAR_LANE_INDEX, tc.VAR_LANE_ID, tc.VAR_ACCEL, tc.VAR_ANGLE,
                                    tc.VAR_LANE_ID, tc.VAR_ACCELERATION, tc.VAR_COLOR, tc.VAR_LANE_INDEX,
                                    tc.TRAFFICLIGHT_TYPE_STATIC])
    traci.simulation.subscribe([tc.VAR_ARRIVED_VEHICLES_NUMBER,
                                tc.VAR_ARRIVED_VEHICLES_IDS,
                                tc.VAR_DEPARTED_VEHICLES_NUMBER,
                                tc.VAR_DEPARTED_VEHICLES_IDS,
                                tc.VAR_COLLIDING_VEHICLES_NUMBER,
                                tc.VAR_COLLIDING_VEHICLES_IDS])
    traci.lane.setAllowed('-299.0.00_1', [])
    traci.lane.setAllowed('-299.0.00_0', [])
    # 设置所有车道的最大通行速度
    for id in traci.lane.getIDList():
        traci.lane.setMaxSpeed(id, 18)
    # 编队车辆配置
    plexe = Plexe()
    traci.addStepListener(plexe)

    # ============================路由信息解析=======================================
    accident, rateLimiting, rampControl, emergencyLane, \
    specialLane, platoonSwitch, badWeather, car_config = parse_route(rou_cfg)
    rc = RoutConfig(rou_cfg['taskId'], rou_cfg['rouId'], rou_cfg['userId'], rou_cfg['name'], rou_cfg['rouUrl'],
                    rou_cfg['route'], rou_cfg['sceneInfo'], rou_cfg['type'], rou_cfg['source'])

    # 主路限速
    speed_limit_area_point_list = []

    # 排序后的门架集合

    for i in range(len(rateLimiting)):
        speedLimitPoints, speeds, speed_gantry_asc_one = get_speed_limit_points(frame_info,
                                                                                rateLimiting[i]['speedLimitPoints'],
                                                                                rateLimiting[i]['speeds'])
        speed_limit_area_point_list.append(rateLimiting[i]['areaPoints'])
        speed_limit_point_list.append(speedLimitPoints)
        speed_limit_list.append(speeds)
        speed_gantry_asc.append(speed_gantry_asc_one)

    # colliding_vehicles_number = traci.simulation.subscribe(tc.VAR_COLLIDING_VEHICLES_NUMBER)
    # traci.edge.setMaxSpeed('-296.0.00', 0)
    # 关闭车道
    # traci.lane.setDisallowed('-296.0.00_3', ['passenger', 'custom1', 'bus', 'truck'])
    traci.lane.setDisallowed('371.0.00_0', ['passenger', 'custom1', 'bus', 'truck'])
    traci.lane.setDisallowed('-361.0.00_0', ['passenger', 'custom1', 'bus', 'truck'])
    traci.lane.setDisallowed('-254.0.00_0', ['passenger', 'custom1', 'bus', 'truck'])

    # ====================================非仿真初始化============================================
    # kafka数据初始化
    producer = KafkaProducer(bootstrap_servers=KAFKA_HOST, key_serializer=str.encode,
                             value_serializer=lambda x: json.dumps(x).encode('utf-8'))
    # ======================发送事件信息===============================================
    sumo_main1init_util.send_event_message(producer, accident, badWeather, rateLimiting, rampControl, emergencyLane,
                                           specialLane, frame_info, task_id)
    # 获取虚拟设备状态kafka数据
    vir_thread = threading.Thread(target=kafka_util.receive_message, args=(userId, task_id, resource))
    vir_thread.start()

    # 获取红绿灯id
    tlss = sumo_net_instance.getTrafficLights()
    tl_ids = [tl.getID() for tl in tlss]
    while (True):
        try:
            start_ts = time.time()
            # 车辆到达目的地消失会自动添加车辆
            sumo_main1init_util.veh_arrive_automatic_add(traci, platoonSwitch, rou_cfg, plexe, sumo_net_instance)
            # ======================= 添加车辆 =======================
            sumo_main1init_util.add_vehicles(car_config, sumo_net_instance, platoonSwitch, rou_cfg, plexe, producer,
                                             userId, task_id, resource, leader_ids, start_ts)
            car_config.clear()
            add_vehicles_ts = time.time()
            print("添加车辆： ", add_vehicles_ts - start_ts)
            # 获取当前时刻指定类型的车辆 ID 列表
            vtype = "0"
            global_vehicles = traci.polygon.getContextSubscriptionResults('GLOBAL_POLYGON_CENTER')
            arrived_vehicles = traci.polygon.getContextSubscriptionResults('VAR_ARRIVED_VEHICLES_NUMBER')
            if len(arrived_vehicles.keys()) > 0:
                print(arrived_vehicles.keys())
            vehicle_ids = global_vehicles.keys()
            if count_step % 10 == 1 and Plexe_enum.LEAD.value not in vehicle_ids:
                platoonSwitch['type'] = rou_cfg['type']
                topology = platoonUtils.add_vehicles(plexe, platoonUtils.N_VEHICLES, 1, 98, platoonSwitch,
                                                     real_engine=False)
            if count_step % 2 == 1 and topology is not None and Plexe_enum.LEAD.value in vehicle_ids:
                # simulate vehicle communication every 100 ms
                platoonUtils.communicate(plexe, topology)
            # car_ts = time.time()
            # print("发车时间戳", start_ts, car_ts, car_ts - start_ts)
            # ======================= 应急车道 =======================
            # 创建主路限速场景的应急车道
            # if HttpInterface.emergencyLaneConfig is not None:
            emergencyLane = sumo_main1init_util.init_emergency_line(emergencyLane, frame_emergencyLaneConfig, traci,
                                                                    sumo_net_instance, tl_ids)
            emergencyLane = []

            # 控制应急车道

            # if HttpInterface.emergencyLaneControl is not None:
            #     temp_control = HttpInterface.emergencyLaneControl
            #     HttpInterface.emergencyLaneControl = None
            #     edge_id, _, _ = traci.simulation.convertRoad(temp_control['point']['lon'], temp_control['point']['lat'],
            #                                                  True)
            #     edge = sumo_net_instance.getEdge(edge_id)
            #     edge = sumo_utils.findNewEdge(edge)
            #     sumo_utils.controlEmergencyLane(temp_control['switch'], edge)
            # print(vir_ramp_light)
            # 匝道管控
            sumo_main1init_util.init_ramp_control(vir_ramp_light, traci)
            # 控制应急车道
            sumo_main1init_util.control_emergency_line(emergency_dict, frame_emergencyLaneControl, sumo_net_instance,
                                                       tl_ids)
            emergency_line_ts = time.time()
            print("应急车道： ", emergency_line_ts - start_ts)
            # ======================= 专用车道 =======================
            specialLane = sumo_main1init_util.init_specialLane(specialLane, frame_emergencyLaneConfig, traci,
                                                               sumo_net_instance)
            specialLane = []
            # 控制专用车道
            sumo_main1init_util.control_specialLane(special_dict, frame_emergencyLaneControl, sumo_net_instance, tl_ids)
            specialLane_ts = time.time()
            print("控制专用车道： ", specialLane_ts - start_ts)
            # ======================= 主路限速场景 =======================
            # SPEED_LIMIT_SIGN = True
            sumo_main1init_util.init_mainRoad_speedLimit(SPEED_LIMIT_SIGN, speed_limit_area_point_list,
                                                         SPEED_LIMIT_POLYGON_SIGN, limit_polygon, sumo_net_instance,
                                                         traci, speed_limit_point_list, speed_limit_list)
            speedLimit_ts = time.time()
            print("主路限速场景： ", speedLimit_ts - start_ts)
            # ======================= 事故区场景（车道禁用） =======================
            accident = sumo_main1init_util.init_accident(accident, plexe, vehicle_ids)

            accident = []
            accident_ts = time.time()
            print("事故区场景： ", accident_ts - start_ts)
            # ======================= 恶劣天气场景 =======================
            sumo_main1init_util.init_bad_weather(badWeather, BAD_WEATHER_POLYGON_SIGN, bad_weather_polygon, traci,
                                                 sumo_net_instance)
            badWeather_ts = time.time()
            print("恶劣天气场景： ", badWeather_ts - start_ts)
            # ======================= 发送数据封装 =======================

            sumo_main1init_util.send_kafka_message(global_vehicles, vtype, sumo_net_instance, traci, userId, task_id,
                                                   resource, start_ts, producer)

            kafka_message_ts = time.time()
            print("发送数据封装： ", kafka_message_ts - start_ts)
            traci.simulationStep()  # 以0.1s的步长仿真
            end_ts = time.time()
            ts = int(start_ts * 1000)
            end_ts = int(end_ts * 1000)
            # print("时间戳", ts, end_ts, end_ts - ts)
            diff_time = end_ts - ts
            if diff_time < 100:
                time.sleep((100 - diff_time) * 0.001)
            count_step += 1
        except TraCIException as e:
            print(str(e))
            traci.simulationStep()


# 随机仿真
def main2(userId=None, task_id=None, rou_cfg=None, sumo_cfg_file=None, sumo_net_file=None, gui=True, resource=None):
    global count_step, limit_polygon, bad_weather_polygon, topology, SPEED_LIMIT_SIGN, vir_gantry_dict, \
        speed_limit_point_list, speed_limit_list, speed_gantry_asc, arrived_depart, locusQueue
    # ======================路网信息初始化============================
    frame_info = get_gantry_info()
    frame_emergencyLaneConfig = get_emergencyLaneConfig_info()
    frame_emergencyLaneControl = get_emergencyLaneControl_info()

    sumo_net_instance = sumolib.net.readNet(sumo_net_file, withInternal=True, withLatestPrograms=True)
    sumo_utils.start_sumo(sumo_cfg_file, False, gui=gui)
    traci.polygon.add('GLOBAL_POLYGON_CENTER', GLOBAL_POLYGON_CENTER, (1, 0, 1))
    traci.polygon.subscribeContext('GLOBAL_POLYGON_CENTER',
                                   tc.CMD_GET_VEHICLE_VARIABLE, 10000,
                                   [tc.VAR_SPEED, tc.VAR_DECEL, tc.VAR_DISTANCE, tc.VAR_TYPE, tc.VAR_POSITION,
                                    tc.VAR_ROAD_ID, tc.VAR_LANE_INDEX, tc.VAR_LANE_ID, tc.VAR_ACCEL, tc.VAR_ANGLE,
                                    tc.VAR_LANE_ID, tc.VAR_ACCELERATION, tc.VAR_COLOR, tc.VAR_LANE_INDEX,
                                    tc.TRAFFICLIGHT_TYPE_STATIC])
    traci.simulation.subscribe([tc.VAR_ARRIVED_VEHICLES_NUMBER,
                                tc.VAR_ARRIVED_VEHICLES_IDS,
                                tc.VAR_DEPARTED_VEHICLES_NUMBER,
                                tc.VAR_DEPARTED_VEHICLES_IDS,
                                tc.VAR_COLLIDING_VEHICLES_NUMBER,
                                tc.VAR_COLLIDING_VEHICLES_IDS])
    traci.lane.setAllowed('-299.0.00_1', [])
    traci.lane.setAllowed('-299.0.00_0', [])
    # 设置所有车道的最大通行速度
    for id in traci.lane.getIDList():
        traci.lane.setMaxSpeed(id, 18)
    # 编队车辆配置
    plexe = Plexe()
    traci.addStepListener(plexe)

    # ============================路由信息解析=======================================
    accident, rateLimiting, rampControl, emergencyLane, \
    specialLane, platoonSwitch, badWeather, car_config = parse_route(rou_cfg)
    # 主路限速
    speed_limit_area_point_list = []

    # 排序后的门架集合

    for i in range(len(rateLimiting)):
        speedLimitPoints, speeds, speed_gantry_asc_one = get_speed_limit_points(frame_info,
                                                                                rateLimiting[i]['speedLimitPoints'],
                                                                                rateLimiting[i]['speeds'])
        speed_limit_area_point_list.append(rateLimiting[i]['areaPoints'])
        speed_limit_point_list.append(speedLimitPoints)
        speed_limit_list.append(speeds)
        speed_gantry_asc.append(speed_gantry_asc_one)

    # colliding_vehicles_number = traci.simulation.subscribe(tc.VAR_COLLIDING_VEHICLES_NUMBER)
    # traci.edge.setMaxSpeed('-296.0.00', 0)
    # 关闭车道
    # traci.lane.setDisallowed('-296.0.00_3', ['passenger', 'custom1', 'bus', 'truck'])
    traci.lane.setDisallowed('371.0.00_0', ['passenger', 'custom1', 'bus', 'truck'])
    traci.lane.setDisallowed('-361.0.00_0', ['passenger', 'custom1', 'bus', 'truck'])
    traci.lane.setDisallowed('-254.0.00_0', ['passenger', 'custom1', 'bus', 'truck'])

    # ====================================非仿真初始化============================================
    # kafka数据初始化
    producer = KafkaProducer(bootstrap_servers=KAFKA_HOST, key_serializer=str.encode,
                             value_serializer=lambda x: json.dumps(x).encode('utf-8'))
    # 获取虚拟设备状态kafka数据
    vir_thread = threading.Thread(target=kafka_util.receive_message, args=(userId, task_id, resource))
    vir_thread.start()

    # 获取红绿灯id
    tlss = sumo_net_instance.getTrafficLights()
    tl_ids = [tl.getID() for tl in tlss]
    while (True):
        try:
            start_ts = time.time()

            # 车辆到达目的地消失会自动添加车辆
            sumo_main1init_util.veh_arrive_automatic_add(traci, platoonSwitch, rou_cfg, plexe, sumo_net_instance)
            # ======================= 添加车辆 =======================
            sumo_main1init_util.add_vehicles(car_config, sumo_net_instance, platoonSwitch, rou_cfg, plexe, producer,
                                             userId, task_id, resource, leader_ids, start_ts)
            car_config.clear()
            add_vehicles_ts = time.time()
            print("添加车辆： ", add_vehicles_ts - start_ts)
            # 获取当前时刻指定类型的车辆 ID 列表
            vtype = "0"
            global_vehicles = traci.polygon.getContextSubscriptionResults('GLOBAL_POLYGON_CENTER')
            arrived_vehicles = traci.polygon.getContextSubscriptionResults('VAR_ARRIVED_VEHICLES_NUMBER')

            # print("locusQueue",locusQueue)
            # 添加人驾车、网联车、自动驾驶车
            # print("====================",global_vehicles.keys())

            if len(arrived_vehicles.keys()) > 0:
                print(arrived_vehicles.keys())
            vehicle_ids = global_vehicles.keys()
            if count_step % 10 == 1 and Plexe_enum.LEAD.value not in vehicle_ids:
                platoonSwitch['type'] = rou_cfg['type']
                topology = platoonUtils.add_vehicles(plexe, platoonUtils.N_VEHICLES, 1, 98, platoonSwitch,
                                                     real_engine=False)
            if count_step % 2 == 1 and topology is not None and Plexe_enum.LEAD.value in vehicle_ids:
                sumo_main1init_util.plexe_update_lane_access(Plexe_enum.FOLLOW_THREE.value, traci)
                # simulate vehicle communication every 100 ms
                platoonUtils.communicate(plexe, topology)
            # car_ts = time.time()
            # print("发车时间戳", start_ts, car_ts, car_ts - start_ts)
            # ======================= 应急车道 =======================
            # 创建主路限速场景的应急车道
            # if HttpInterface.emergencyLaneConfig is not None:
            emergencyLane = sumo_main1init_util.init_emergency_line(emergencyLane, frame_emergencyLaneConfig, traci,
                                                                    sumo_net_instance, tl_ids)
            emergencyLane = []
            # 匝道管控
            sumo_main1init_util.init_ramp_control(vir_ramp_light, traci)
            # 控制应急车道
            sumo_main1init_util.control_emergency_line(emergency_dict, frame_emergencyLaneControl, sumo_net_instance,
                                                       tl_ids)
            emergency_line_ts = time.time()
            print("应急车道： ", emergency_line_ts - start_ts)
            # ======================= 专用车道 =======================
            specialLane = sumo_main1init_util.init_specialLane(specialLane, frame_emergencyLaneConfig, traci,
                                                               sumo_net_instance)
            specialLane = []
            # 控制专用车道
            sumo_main1init_util.control_specialLane(special_dict, frame_emergencyLaneControl, sumo_net_instance, tl_ids)
            specialLane_ts = time.time()
            print("控制专用车道： ", specialLane_ts - start_ts)
            # ======================= 主路限速场景 =======================
            sumo_main1init_util.init_mainRoad_speedLimit(SPEED_LIMIT_SIGN, speed_limit_area_point_list,
                                                         SPEED_LIMIT_POLYGON_SIGN, limit_polygon, sumo_net_instance,
                                                         traci, speed_limit_point_list, speed_limit_list)
            speedLimit_ts = time.time()
            print("主路限速场景： ", speedLimit_ts - start_ts)
            # ======================= 事故区场景（车道禁用） =======================
            # accident=sumo_main1init_util.init_accident(accident,plexe,vehicle_ids)
            # accident=[]
            # accident_ts = time.time()
            # print("事故区场景： ", accident_ts - start_ts)
            # # ======================= 恶劣天气场景 =======================
            # sumo_main1init_util.init_bad_weather(badWeather,BAD_WEATHER_POLYGON_SIGN,bad_weather_polygon,traci,sumo_net_instance)
            # badWeather_ts = time.time()
            # print("恶劣天气场景： ", badWeather_ts - start_ts)
            # 随机事件仿真
            sumo_main1init_util.randomSimulation(rou_cfg, traci, accident, plexe, vehicle_ids, badWeather,
                                                 BAD_WEATHER_POLYGON_SIGN, bad_weather_polygon, sumo_net_instance,
                                                 producer, task_id)
            # ======================= 发送数据封装 =======================

            sumo_main1init_util.send_kafka_message(global_vehicles, vtype, sumo_net_instance, traci, userId, task_id,
                                                   resource, start_ts, producer)
            kafka_message_ts = time.time()
            print("发送数据封装： ", kafka_message_ts - start_ts)
            traci.simulationStep()  # 以0.1s的步长仿真
            end_ts = time.time()
            ts = int(start_ts * 1000)
            end_ts = int(end_ts * 1000)
            # print("时间戳", ts, end_ts, end_ts - ts)
            diff_time = end_ts - ts
            if diff_time < 100:
                # time.sleep((100 - diff_time) * 0.001)
                print(1)
            count_step += 1
        except TraCIException as e:
            print(str(e))
            traci.simulationStep()


# 混合交通流仿真仿真
def main3(userId=None, task_id=None, rou_cfg=None, sumo_cfg_file=None, sumo_net_file=None, gui=True, resource=None):
    global count_step, limit_polygon, bad_weather_polygon, topology, SPEED_LIMIT_SIGN, vir_gantry_dict, \
        speed_limit_point_list, speed_limit_list, speed_gantry_asc, arrived_depart, locusQueue, real_vehicle_queue
    # ======================路网信息初始化============================

    frame_info = get_gantry_info_HTF()

    sumo_net_instance = sumolib.net.readNet(sumo_net_file, withInternal=True, withLatestPrograms=True)
    sumo_utils.start_sumo(sumo_cfg_file, False, gui=True)
    # 选择需要订阅的参数
    traci.polygon.add('GLOBAL_POLYGON_CENTER', GLOBAL_POLYGON_CENTER, (1, 0, 1))
    traci.polygon.subscribeContext('GLOBAL_POLYGON_CENTER',
                                   tc.CMD_GET_VEHICLE_VARIABLE, 10000,
                                   [tc.VAR_SPEED, tc.VAR_DECEL, tc.VAR_DISTANCE, tc.VAR_TYPE, tc.VAR_POSITION,
                                    tc.VAR_ROAD_ID, tc.VAR_LANE_INDEX, tc.VAR_LANE_ID, tc.VAR_ACCEL, tc.VAR_ANGLE,
                                    tc.VAR_LANE_ID, tc.VAR_ACCELERATION, tc.VAR_COLOR, tc.VAR_LANE_INDEX,
                                    tc.TRAFFICLIGHT_TYPE_STATIC])
    traci.simulation.subscribe([tc.VAR_ARRIVED_VEHICLES_NUMBER,
                                tc.VAR_ARRIVED_VEHICLES_IDS,
                                tc.VAR_DEPARTED_VEHICLES_NUMBER,
                                tc.VAR_DEPARTED_VEHICLES_IDS,
                                tc.VAR_COLLIDING_VEHICLES_NUMBER,
                                tc.VAR_COLLIDING_VEHICLES_IDS])
    # 设置所有车道的最大通行速度
    for id in traci.lane.getIDList():
        traci.lane.setMaxSpeed(id, 18)
    # ============================路由信息解析=======================================
    rateLimiting, rampControl, badWeather, car_config = MTF_parse_route(rou_cfg)
    # 主路限速
    speed_limit_area_point_list = []

    # 排序后的门架集合
    print(rateLimiting,frame_info)

    for i in range(len(rateLimiting)):
        speedLimitPoints, speeds, speed_gantry_asc_one = get_speed_limit_points(frame_info,
                                                                                rateLimiting[i]['speedLimitPoints'],
                                                                                rateLimiting[i]['speeds'])
        """
        speed_limit_area_point_list: 前端传过来的限速区域，用四个点多边形确定限速区域范围
        speed_limit_point_list：排序后的门架经纬度
        
        """
        speed_limit_area_point_list.append(rateLimiting[i]['areaPoints'])
        speed_limit_point_list.append(speedLimitPoints)
        speed_limit_list.append(speeds)
        speed_gantry_asc.append(speed_gantry_asc_one)

    # ====================================非仿真初始化============================================
    # kafka数据初始化
    producer = KafkaProducer(bootstrap_servers=KAFKA_HOST, key_serializer=str.encode,
                             value_serializer=lambda x: json.dumps(x).encode('utf-8'))
    # 获取虚拟设备状态kafka数据
    vir_thread = threading.Thread(target=kafka_util.MTF_receive_message, args=(userId, task_id, resource))
    vir_thread.start()

    # 获取网联车、人驾车和自动驾驶车kafka数据
    rv_thread = threading.Thread(target=kafka_util.receive_message_of_AV_vehicle, args=(userId, task_id, resource))
    rv_thread.start()

    # websocket初始化
    # thread3 = threading.Thread(target=WebSocketServer)
    # thread3.start()

    while (True):
        try:
            start_ts = time.time()

            # 车辆到达目的地消失会自动添加车辆
            sumo_main1init_util.MTF_veh_arrive_automatic_add(traci, sumo_net_instance)
            # ======================= 添加车辆 =======================
            sumo_main1init_util.MTF_add_vehicles(car_config, sumo_net_instance)
            car_config.clear()
            global_vehicles = traci.polygon.getContextSubscriptionResults('GLOBAL_POLYGON_CENTER')
            # arrived_vehicles = traci.polygon.getContextSubscriptionResults('VAR_ARRIVED_VEHICLES_NUMBER')

            """
            测试代码
            """
            # for car_id in global_vehicles.keys():
            #     if traci.vehicle.couldChangeLane(car_id, -1):
            #         traci.vehicle.changeLaneRelative(car_id, -1, 2)
            #
            #     if traci.vehicle.couldChangeLane(car_id, 1):
            #         traci.vehicle.changeLaneRelative(car_id, 1, 2)
            # print("locusQueue",locusQueue)
            # 添加人驾车、网联车、自动驾驶车
            # print("====================",global_vehicles.keys())

            # sumo_main1init_util.vehicle_add_HDV_AV_CV(locusQueue, traci, sumo_net_instance, global_vehicles, count_step)
            sumo_main1init_util.vehicle_add_HDV_AV_CV1(real_vehicle_queue, traci, sumo_net_instance, global_vehicles,
                                                       count_step)
            # ======================= 匝道管控场景 =======================
            # vir_ramp_light = 1
            sumo_main1init_util.MTF_init_ramp_control(vir_ramp_light, traci)

            # SPEED_LIMIT_SIGN = True
            # ======================= 主路限速场景 =======================
            SPEED_LIMIT_SIGN = True
            sumo_main1init_util.init_mainRoad_speedLimit(SPEED_LIMIT_SIGN, speed_limit_area_point_list,
                                                         SPEED_LIMIT_POLYGON_SIGN, limit_polygon, sumo_net_instance,
                                                         traci, speed_limit_point_list, speed_limit_list)
            # ======================= 恶略天气场景 =======================
            if True:
                print("!!!!!!",badWeather, BAD_WEATHER_POLYGON_SIGN, bad_weather_polygon)
            sumo_main1init_util.MTF_init_bad_weather(badWeather, BAD_WEATHER_POLYGON_SIGN, bad_weather_polygon, traci,
                                                     sumo_net_instance,producer,userId,task_id,resource)
            badWeather = []

            # ======================= 发送数据封装 =======================

            sumo_main1init_util.MTF_send_kafka_message(depart_info,global_vehicles, sumo_net_instance, traci, userId,
                                                       task_id,resource, start_ts, producer)
            # kafka_message_ts = time.time()
            # print("发送数据封装： ", kafka_message_ts - start_ts)
            traci.simulationStep()  # 以0.1s的步长仿真
            end_ts = time.time()
            ts = int(start_ts * 1000)
            end_ts = int(end_ts * 1000)
            # print("时间戳", end_ts - ts)
            diff_time = end_ts - ts
            if diff_time < 100:
                print("时间戳", end_ts - ts)
                time.sleep((100 - diff_time) * 0.001)
                # print(1)
            count_step += 1
        except TraCIException as e:
            print(str(e))
            traci.simulationStep()


# 主函数
if __name__ == "__main__":
    sumo_net_file = "./webgl/6e2fccc4-f09d-411e-93ba-407b6f70c0f9.net.xml"  # 路网文件
    sumo_cfg_file = "./webgl/长安大学_openDrive_v0.sumocfg"  # 路网文件
    main3(sumo_cfg_file=sumo_cfg_file, sumo_net_file=sumo_net_file)
